import React from 'react';

import { container } from '../container';
import { StatusValue } from '../typings';
import { PipeItem } from '../typings/Pipe';
import { get as lodashGet } from 'lodash';

export const bizUtil = {
  /**
   * 执行逻辑表达式
   * @param lc
   * @param dta
   */
  executeLogicCondition(lc: StatusValue, data: object) {
    // 如果是boolean型，直接返回lc
    if (typeof lc === 'boolean') {
      return lc;
    }
    // 如果是无值，直接返回false
    if (!lc) {
      return false;
    }
    // 计算左值
    const leftValue = bizUtil.excuteExpression(lc.left, data);
    // 计算右值
    const rightValue = bizUtil.excuteExpression(lc.right, data);

    // 执行判断
    const fn = new Function('lVal', 'rVal', 'op', `return lVal ${lc.op} rVal;`);
    const result = fn.call(null, leftValue, rightValue, lc.op);

    return result;
  },

  /**
   * 计算表达式
   * @param exp
   * @param data
   * @returns
   */
  excuteExpression(exp: string, data: object) {
    if (typeof exp !== 'string') {
      return exp;
    }
    const dataKeys = Object.keys(data);
    //  console.log(dataKeys, 'data');

    //  是否有变量
    let hasVar = false;
    // 提取keypath
    const keypath = exp.replace(/\{[$_a-zA-Z0-9]+\}/g, (match: string) => {
      const matchVar = match.replace('{', '').replace('}', '');

      if (dataKeys.includes(matchVar)) {
        // console.log(matchVar, 'matchVar');
        // console.log(exp, 'exp');

        hasVar = true;
        return matchVar;
      }
      return match;
    });

    // let str = '{item}.canDelete';
    // console.log(str.match(/^\{^\}/g), 'ssss');

    console.log(keypath, 'keypath');
    // console.log(data, 'data');
    // console.log(exp, 'exp');
    // console.log(lodashGet(data, keypath), 'lodashGet(data, keypath)');

    return hasVar ? lodashGet(data, keypath) : exp;
  },

  executePipes(value: any, pipes?: PipeItem[]): React.ReactNode {
    // 处理pipe
    if (!pipes || pipes.length <= 0) {
      return value;
    }

    // 处理Pipe报错
    return pipes.reduce((result: any, item: any) => {
      const pipeItem = container.getPipe(item.name);
      if (!pipeItem) {
        return result;
      }
      return pipeItem.transform(result, item.options);
    }, value);
  },
};
